#include							"Processor.h"
#include							"QtAsyncTcpSocket.h"
#include							"RotatingBuffer.h"

QtAsyncTcpSocket::QtAsyncTcpSocket(Processor & proc) : _proc(proc), _current_msg(0)
{
	_buffer = new RotatingBuffer(4096);
	_buffer->init();
}

QtAsyncTcpSocket::~QtAsyncTcpSocket()
{
	if (_buffer)
		delete _buffer;
}

void								QtAsyncTcpSocket::init()
{
	connect(&_socket, SIGNAL(readyRead()), this, SLOT(handle_read()));
}

void								QtAsyncTcpSocket::sendOrder(IOrder* order)
{
	unsigned short					size = order->size();

	this->write(order->send(), size + sizeof(unsigned short));
}

size_t								QtAsyncTcpSocket::write(byte *data, size_t len)
{
	_socket.write((const char *)data, len);
	return (0);
}


void								QtAsyncTcpSocket::close()
{
	_socket.close();
}

void								QtAsyncTcpSocket::connectToHost(const std::string & ip, const std::string & port)
{
	_socket.connectToHost(QString(ip.c_str()), QString(port.c_str()).toShort());
	std::cout << "connected to host " << ip << ":" << port << std::endl;
}

void								QtAsyncTcpSocket::handle_read()
{
	size_t							received = 0;

	received = _socket.read((char*)_tmp_buf, 4096);
	onReceive(received);
}

void								QtAsyncTcpSocket::onReceive(size_t bytes_transferred)
{
	for (size_t cnt = 0; cnt < bytes_transferred; ++cnt)
		_buffer->write(_tmp_buf[cnt]);
	int test = _buffer->size();
	if (!_current_msg && _buffer->size() >= 2)
		getOrderSize();
	while (_buffer->size() > 0 && _buffer->size() >= _current_msg)
	{
		std::vector<byte>		*harvest = new std::vector<byte>;
		for (unsigned short cnt = 0; cnt < _current_msg; ++cnt)
			harvest->push_back(_buffer->read());
		_proc(harvest, _id);
		_current_msg = 0;
		if (_buffer->size() >= 2)
			getOrderSize();
	}
}

void								QtAsyncTcpSocket::getOrderSize()
{
	byte size[2];

	size[0] = _buffer->read();
	size[1] = _buffer->read();
	_current_msg = *((unsigned short*) size);
}

std::string							QtAsyncTcpSocket::getIp()
{
	return *new std::string;
}